using UnityEngine;
using Watermelon.Map;
using Watermelon.SkinStore;

namespace Watermelon
{
    public class GameController : MonoBehaviour
    {
        private static GameController gameController;

        [DrawReference]
        [SerializeField] GameData data;

        [LineSpacer]
        [SerializeField] UIController uiController;
        [SerializeField] MusicSource musicSource;

        private LevelController levelController;
        private ParticlesController particlesController;
        private FloatingTextController floatingTextController;
        private PUController powerUpController;
        private MapBehavior mapBehavior;
        private TutorialController tutorialController;
        private SkinController skinController;
        private SkinStoreController skinStoreController;

        public static GameData Data => gameController.data;

        private static bool isGameActive;
        public static bool IsGameActive => isGameActive;

        private void Awake()
        {
            gameController = this;

            // Cache components
            gameObject.CacheComponent(out particlesController);
            gameObject.CacheComponent(out floatingTextController);
            gameObject.CacheComponent(out levelController);
            gameObject.CacheComponent(out powerUpController);
            gameObject.CacheComponent(out mapBehavior);
            gameObject.CacheComponent(out tutorialController);
            gameObject.CacheComponent(out skinController);
            gameObject.CacheComponent(out skinStoreController);

            uiController.Init();

            particlesController.Init();
            floatingTextController.Init();
            musicSource.Init();

            skinController.Init();
            skinStoreController.Init(skinController);
            powerUpController.Init();
            levelController.Init();
            tutorialController.Init();

            uiController.InitPages();

            musicSource.Activate();
        }

        private void Start()
        {
            AdsManager.EnableBanner();

            if (LevelAutoRun.CheckIfNeedToAutoRunLevel())
            {
                LoadLevel(LevelAutoRun.GetLevelIndex());
            }
            else
            {
                if (LevelController.DisplayedLevelIndex == 0 && data.ShowTutorial)
                {
                    ITutorial firstLevelTutorial = TutorialController.GetTutorial(TutorialID.FirstLevel);

                    if (firstLevelTutorial != null && !firstLevelTutorial.IsFinished)
                    {
                        firstLevelTutorial.StartTutorial();

                        LoadLevel(0);
                    }
                    else
                    {
                        OpenMainMenu();
                    }
                }
                else
                {
                    OpenMainMenu();
                }
            }

            GameLoading.MarkAsReadyToHide();
        }

        private void OpenMainMenu()
        {
            mapBehavior.Show();

            // Display default page
            UIController.ShowPage<UIMainMenu>();
        }

        public static void LoadLevel(int index, SimpleCallback onLevelLoaded = null)
        {
            AdsManager.ShowInterstitial(null);

            LivesSystem.LockLife();

            gameController.mapBehavior.Hide();

            AdsManager.EnableBanner();

            UIController.ShowPage<UIGame>();

            isGameActive = true;

            gameController.levelController.LoadLevel(index, onLevelLoaded);
        }

        public static void OnLevelCompleted()
        {
            if (!isGameActive)
                return;

            AudioController.PlaySound(AudioController.AudioClips.levelComplete);

            UIGame gameUI = UIController.GetPage<UIGame>();
            gameUI.PowerUpsUIController.OnLevelFinished();

            UIController.HidePage<UIGame>(() =>
            {
                UIController.ShowPage<UIComplete>();
            });

            isGameActive = false;
        }

        public static void OnLevelFailed()
        {
            if (!isGameActive)
                return;

            UIGame gameUI = UIController.GetPage<UIGame>();
            gameUI.PowerUpsUIController.OnLevelFinished();

            UIController.HidePage<UIGame>(() =>
            {
                UIController.ShowPage<UIGameOver>();
            });

            isGameActive = false;
        }

        public static void LoadNextLevel(SimpleCallback onLevelLoaded = null)
        {
            LoadLevel(LevelController.DisplayedLevelIndex, onLevelLoaded);
        }

        public static void ReplayLevel()
        {
            isGameActive = false;

            Overlay.Show(0.3f, () =>
            {
                UIGame gameUI = UIController.GetPage<UIGame>();
                gameUI.PowerUpsUIController.OnLevelFinished();

                LoadLevel(LevelController.DisplayedLevelIndex);

                Overlay.Hide(0.3f);
            }, true);
        }

        public static void ReplayStage()
        {
            isGameActive = true;

            UIGame gameUI = UIController.GetPage<UIGame>();
            gameUI.PowerUpsUIController.OnLevelFinished();

            gameController.levelController.ReloadStage();
        }

        public static void ReturnToMenu()
        {
            isGameActive = false;

            LevelController.UnloadLevel();

            gameController.mapBehavior.Show();

            AdsManager.ShowInterstitial(null);

            UIController.ShowPage<UIMainMenu>();

            AdsManager.EnableBanner();
        }

        public static void Revive()
        {
            isGameActive = true;
            LevelController.IsRaycastEnabled = true;
        }
    }
}